#include "sms.h"

static listview_list_free(ListView *lv);

ListView *listview_new(GooCanvasItem *parent,gdouble x,gdouble y,Theme * theme,Listview_type lt){
	int tmpx,tmpy,i;
	ListView *lv;

	lv = (ListView *) g_malloc0(sizeof(ListView)+1);
	lv->parent=parent;
	lv->x=x;
	lv->y=y;
	lv->w=gdk_pixbuf_get_width(theme->pic[THEME_PIC_LEFT_LISTVIEW_FRAME]);
	lv->h=gdk_pixbuf_get_height(theme->pic[THEME_PIC_LEFT_LISTVIEW_FRAME]);
	lv->fw=(lv->w - gdk_pixbuf_get_width(theme->pic[THEME_PIC_LEFT_LISTVIEW_BACKGROUND]))/2;
	tmpx = gdk_pixbuf_get_width(theme->pic[THEME_PIC_LEFT_LISTVIEW_FG]);
	tmpy = gdk_pixbuf_get_height(theme->pic[THEME_PIC_LEFT_LISTVIEW_FG]);
	lv->view_count=gdk_pixbuf_get_height(theme->pic[THEME_PIC_LEFT_LISTVIEW_BACKGROUND]) / tmpy;
	printf("view count: %d\n tmpy: %d\n", lv->view_count, tmpy);
	
	lv->cavas = goo_canvas_group_new(parent, "x",lv->x, "y",lv->y,"width",lv->w,"height",lv->h, NULL);
	lv->frame = goo_canvas_image_new (lv->cavas, theme->pic[THEME_PIC_LEFT_LISTVIEW_FRAME], 0,0,"scale-to-fit", TRUE,NULL);
	lv->group = goo_canvas_group_new(lv->cavas, "x",lv->fw, "y",lv->fw,"width",lv->w - lv->fw*2,"height",lv->h - lv->fw*2, NULL);
	
	lv->text=(GooCanvasItem**)g_malloc0(sizeof(GooCanvasItem*)*lv->view_count+1);
	lv->icon=(GooCanvasItem**)g_malloc0(sizeof(GooCanvasItem*)*lv->view_count+1);
	
	lv->background = goo_canvas_image_new (lv->group, theme->pic[THEME_PIC_LEFT_LISTVIEW_BACKGROUND], 0, 0,"scale-to-fit", TRUE,NULL);
	lv->highlight = goo_canvas_image_new (lv->group,theme->pic[THEME_PIC_LEFT_LISTVIEW_FG],0, 0,"scale-to-fit", TRUE,NULL);

	lv->theme = theme;

	if(lt == LISTVIEW_NONE){
		for(i=0;i<lv->view_count;i++){
			lv->text[i] = goo_canvas_text_new(lv->group, "", 10, i*tmpy+tmpy/2, 280, GTK_ANCHOR_WEST, "font",
								theme->font[THEME_FONT_SMALL],"ellipsize",PANGO_ELLIPSIZE_END,NULL);
		}
	}else if(lt == LISTVIEW_ICON){
		int icon_x;
		icon_x = gdk_pixbuf_get_width(theme->pic[THEME_PIC_LEFT_LISTVIEW_ICON]);
		for(i=0;i<lv->view_count;i++){
			lv->icon[i] = goo_canvas_image_new (lv->group, NULL, 0,i*tmpy,"scale-to-fit", TRUE,NULL);
			lv->text[i] = goo_canvas_text_new(lv->group,"", tmpy+icon_x, i*tmpy+tmpy/2, 280, GTK_ANCHOR_WEST,
								"font",theme->font[THEME_FONT_SMALL],"ellipsize",PANGO_ELLIPSIZE_END,
								NULL);
		}		
	}

	listview_list_init(lv);
	
	return lv;
}

/*ListView *listview_no_frame_bg_new(GooCanvasItem *parent, gdouble x, gdouble y,
		                           GdkPixbuf *list_item_fg, GdkPixbuf *list_item_icon,
		                           GdkPixbuf *listview_bg,
		                           Theme *theme, Listview_type lt) {
	printf("start func %s\n" ,__FUNCTION__);
	int tmpx,tmpy,i;
	ListView *lv;

	lv = (ListView *) g_malloc0(sizeof(ListView)+1);
	lv->parent=parent;
	lv->x=x;
	lv->y=y;

	lv->w=gdk_pixbuf_get_width(listview_bg);
	lv->h=gdk_pixbuf_get_height(listview_bg);
	lv->fw=0;
	tmpx = gdk_pixbuf_get_width(list_item_fg);
	tmpy = gdk_pixbuf_get_height(list_item_fg);
	lv->view_count=lv->h / tmpy;

	lv->cavas = goo_canvas_group_new(parent, "x",lv->x, "y",lv->y,"width",lv->w,"height",lv->h, NULL);
	lv->frame = NULL;
	lv->group = NULL;
	lv->background = listview_bg;

	lv->text=(GooCanvasItem**)g_malloc0(sizeof(GooCanvasItem*)*lv->view_count+1);
	lv->icon=(GooCanvasItem**)g_malloc0(sizeof(GooCanvasItem*)*lv->view_count+1);
	lv->highlight = goo_canvas_image_new (lv->cavas, list_item_fg, 0, 0,"scale-to-fit", TRUE,NULL);
	lv->theme = theme;

	if(lt == LISTVIEW_NONE){
		for(i=0;i<lv->view_count;i++){
			lv->text[i] = goo_canvas_text_new(lv->cavas,"",10, i*tmpy+tmpy/2, 280, GTK_ANCHOR_WEST, "font",
	                    				  theme->font[THEME_FONT_SMALL],"ellipsize",PANGO_ELLIPSIZE_END,NULL);
	    }
	} else if(lt == LISTVIEW_ICON){
			for(i=0;i<lv->view_count;i++){
				lv->icon[i] = goo_canvas_image_new (lv->cavas, list_item_icon, 0, i*tmpy, "scale-to-fit", TRUE, NULL);
				lv->text[i] = goo_canvas_text_new(lv->cavas, "", tmpy+20,i*tmpy+tmpy/2,280,GTK_ANCHOR_WEST,
									              "font", theme->font[THEME_FONT_SMALL], "ellipsize", PANGO_ELLIPSIZE_END,
									              NULL);
			}
	}
	listview_list_init(lv);
}*/

static listview_list_free(ListView *lv){
	int i;
	Node *n;
	if(lv->list_count > 0){
		for(i=lv->list_count;i<0;i--){
			n = g_list_nth_data(lv->items,i);
			if(!n)
				continue;
			if(n->node_pixbuf)
				g_object_unref(n->node_pixbuf);
			if(n->node_buf)
				g_free(n->node_buf);
			free(n);
		}
	}
	if(lv->items)
		g_list_free(lv->items);
	lv->items=NULL;
}

gboolean listview_list_init(ListView *lv){
	listview_list_free(lv);

	lv->view_cur=0;
	lv->list_cur=0;
	lv->list_count=0;
	
}

void listview_set_to(ListView *lv,int id){
	Node *n;
	int i;

	lv->list_cur=id;
	for(i=0;i<lv->view_count;i++){
		n = g_list_nth_data(lv->items,id+i);
		if(n){
			if(lv->text[i]){
				g_object_set(lv->text[i],"text",n->node_buf,NULL);	
				g_object_set(lv->text[i],"fill_color",
							lv->theme->color[THEME_COLOR_TEXT_DISACTIVE],NULL);
			}
			if(lv->icon[i])
				g_object_set(lv->icon[i],"pixbuf",n->node_pixbuf,NULL);
		}else{
			g_object_set(lv->text[i],"text","",NULL);
			g_object_set(lv->icon[i],"pixbuf",NULL,NULL);
		}
	}
}

/*
 * listview_change_frame_pic(ListView *lv,GdkPixbuf *pixbuf)
 *
 * when you use this func to set the frame pic, the prerequisite is the frame pic size
 * must larger than the background pic size
 */
gboolean listview_change_frame_pic(ListView *lv,GdkPixbuf *pixbuf){
	if(lv->frame&&pixbuf)
		g_object_set(lv->frame,"pixbuf",pixbuf,NULL);
	else
		return FALSE;
}

/*
 * listview_change_background_pic(ListView *lv,GdkPixbuf *pixbuf)
 *
 * when you use this func to set the background pic, the prerequisite is the background pic size
 * must smaller than the highlight pic size, meanwhile, the background pic size couldn't larger than
 * the frame pic
 */
gboolean listview_change_background_pic(ListView *lv,GdkPixbuf *pixbuf){
	if(lv->background&&pixbuf)
		g_object_set(lv->background,"pixbuf",pixbuf,NULL);
	else
		return FALSE;
}

gboolean listview_change_highlight_pic(ListView *lv,GdkPixbuf *pixbuf){
	if(lv->highlight&&pixbuf)
		g_object_set(lv->highlight,"pixbuf",pixbuf,NULL);
	else
		return FALSE;
}

gboolean listview_show(ListView *lv){
	printf("start func %s\n" ,__FUNCTION__);
	Node *n;

	listview_set_to(lv,0);
	n = listview_get_cur_item(lv);
	if(lv->theme->color[THEME_COLOR_TEXT_ACTIVE])
		g_object_set(lv->text[lv->view_cur],"fill_color",lv->theme->color[THEME_COLOR_TEXT_ACTIVE],NULL);
	if(n->node_pixbuf_fg) {
		g_object_set(lv->icon[lv->view_cur],"pixbuf",n->node_pixbuf_fg,NULL);
	}
	goo_canvas_item_animate (lv->highlight,0,0,1, 0, TRUE,20,10,GOO_CANVAS_ANIMATE_FREEZE);
}

gboolean listview_add_item(ListView *lv,Node *n ){
#if 0
	Node *n = (Node *)g_malloc0(sizeof(Node)+1);
	n->node_pixbuf = pixbuf_bg;
	n->node_pixbuf_fg = pixbuf_fg;
	n->node_buf = g_strdup(buf);
#endif
	lv->items = g_list_append(lv->items,n);
	lv->list_count = g_list_length(lv->items);
}


Node * listview_get_cur_item(ListView *lv){
	return g_list_nth_data(lv->items,lv->list_cur+lv->view_cur);
}

int listview_get_cur_item_id(ListView *lv){
	return lv->list_cur+lv->view_cur;
}

static void listview_list_translate(ListView *lv,int translate){
	listview_set_to(lv,translate+lv->list_cur);
}

void listview_highlight_translate(ListView *lv,int translate){
	int tmpy;
	Node *n;
	
	tmpy = gdk_pixbuf_get_height(lv->theme->pic[THEME_PIC_LEFT_LISTVIEW_FG]);
	n = listview_get_cur_item(lv);
	if(lv->theme->color[THEME_COLOR_TEXT_DISACTIVE])
		g_object_set(lv->text[lv->view_cur],"fill_color",lv->theme->color[THEME_COLOR_TEXT_DISACTIVE],NULL);
	if(n->node_pixbuf_fg)
		g_object_set(lv->icon[lv->view_cur],"pixbuf",n->node_pixbuf,NULL);
	lv->view_cur = lv->view_cur + translate;
	n = listview_get_cur_item(lv);
	goo_canvas_item_animate (lv->highlight, 0, lv->view_cur*tmpy, 1, 0, TRUE, 20, 10, GOO_CANVAS_ANIMATE_FREEZE);
	if(lv->theme->color[THEME_COLOR_TEXT_ACTIVE])
		g_object_set(lv->text[lv->view_cur], "fill_color", lv->theme->color[THEME_COLOR_TEXT_ACTIVE], NULL);
	if(n->node_pixbuf_fg)
		g_object_set(lv->icon[lv->view_cur], "pixbuf", n->node_pixbuf_fg, NULL);
}

gboolean listview_translate(ListView *lv,int translate){
	Node *n;
	if(translate<0){
		if(translate+lv->list_cur+lv->view_cur<0){
			return FALSE;
		}
		if(lv->view_cur==0){
			listview_list_translate(lv,translate);
			n = listview_get_cur_item(lv);
			if(lv->theme->color[THEME_COLOR_TEXT_ACTIVE])
				g_object_set(lv->text[lv->view_cur],"fill_color",lv->theme->color[THEME_COLOR_TEXT_ACTIVE],
							NULL);
			if(n->node_pixbuf_fg)
				g_object_set(lv->icon[lv->view_cur],"pixbuf",n->node_pixbuf_fg,NULL);
		}else
			listview_highlight_translate(lv,translate);
	}else{
		if(lv->list_count > lv->view_count){
			//translate+lv->view_cur >= lv->view_count || 
			if(translate+lv->list_cur+lv->view_cur >= lv->list_count){
				return FALSE;
			}
		}else if(translate+lv->view_cur >= lv->list_count){
			return FALSE;
		}
		if(lv->view_cur+translate == lv->view_count){
			listview_list_translate(lv,translate);
			n = listview_get_cur_item(lv);
			if(lv->theme->color[THEME_COLOR_TEXT_ACTIVE])
				g_object_set(lv->text[lv->view_cur],"fill_color",
							lv->theme->color[THEME_COLOR_TEXT_ACTIVE],NULL);
			if(n->node_pixbuf_fg)
				g_object_set(lv->icon[lv->view_cur],"pixbuf",n->node_pixbuf_fg,NULL);
		}else
			listview_highlight_translate(lv,translate);
	}

	return TRUE;
}

gboolean listview_set_items_text(ListView *lv,int id,const char *text){
	Node *n = g_list_nth_data(lv->items,id);
	if(n){
		n->node_buf = g_strdup(text);
		return TRUE;
	}else
		return FALSE;
}

const char *listview_get_items_text(ListView *lv,int id){
	Node *n = g_list_nth_data(lv->items,id);
	if(n){
		return n->node_buf;
	}else
		return ;
}

gboolean listview_set_items_icon(ListView *lv,int id,GdkPixbuf *pixbuf){
	Node *n = g_list_nth_data(lv->items,id);
	if(n){
		n->node_pixbuf = pixbuf;
		return TRUE;
	}else
		return FALSE;
}

void listview_destroy(ListView *lv){
	int i;

	listview_list_free(lv);
	for(i=0;i<lv->view_count;i++){
		g_object_unref(lv->icon[i]);
		g_object_unref(lv->text[i]);
	}
	if(lv->highlight)
		g_object_unref(lv->highlight);
	if(lv->background)
		g_object_unref(lv->background);
	if(lv->group)
		g_object_unref(lv->group);
	if(lv->frame)
		g_object_unref(lv->frame);
	if(lv->cavas)
		g_object_unref(lv->cavas);
	g_free(lv);
}

void listview_set_func(ListView *lv,const char *key,gboolean (*func)(ListView *lv,gpointer data)){
	if(strcmp(key,"free-private")==0)
		lv->free_node_private=func;
}

Node * listview_item_create(GdkPixbuf *bg,GdkPixbuf *fg,const char *text,gpointer data)
{
	Node *n = (Node *)g_malloc0(sizeof(Node)+1);
	n->node_pixbuf = bg;
	n->node_pixbuf_fg = fg;
	if(text)		
		n->node_buf = g_strdup(text);
	n->private = data;
	
	return n;
}

void listview_item_destroy(ListView *lv,Node *item)
{
	if(!item)
		return ;
	if(item->private)
	{
		if(lv->free_node_private)
			lv->free_node_private(lv,item->private);
	}
	if(item->node_buf)
		g_free(item->node_buf);
}

Theme *listview_change_theme(Theme *theme, GdkPixbuf *pixbuf_frame, GdkPixbuf *pixbuf_bg,
		                     GdkPixbuf *pixbuf_lfg, GdkPixbuf *pixbuf_icon ){
	int i=0;
	Theme *tmp_theme;
	
	tmp_theme=(Theme *)g_malloc0(sizeof(Theme)+1);
	tmp_theme->name=theme->name;
	
	while(theme->font[i]){
		tmp_theme->font[i] = theme->font[i];
		i++;
	}
	i=0;
	while(theme->color[i]){
		tmp_theme->color[i] = theme->color[i];
		i++;
	}
	i=0;

	while(theme->pic[i]){
		if((i==THEME_PIC_LEFT_LISTVIEW_FRAME)&&pixbuf_frame){
			tmp_theme->pic[i] = pixbuf_frame;
		}else if((i==THEME_PIC_LEFT_LISTVIEW_BACKGROUND)&&pixbuf_bg){
			tmp_theme->pic[i] = pixbuf_bg;
		}else if((i==THEME_PIC_LEFT_LISTVIEW_FG)&&pixbuf_lfg){
			tmp_theme->pic[i] = pixbuf_lfg;
		}else if((i==THEME_PIC_LEFT_LISTVIEW_ICON)&&pixbuf_icon) {
			tmp_theme->pic[i] = pixbuf_icon;
		} else
			tmp_theme->pic[i] = theme->pic[i];
		i++;
	}
	return tmp_theme;
}

void listview_set_pic(gpointer object,GdkPixbuf *pic){
	g_object_set((GooCanvasItem *)object,"pixbuf",pic,NULL);
}
